﻿using GameAnalyticsSDK;
using HWGames.Bundles.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace HWGames {
    public class AdManager : SingletonMonoBehavior<AdManager> {

        private float curInterTime = 0;
        private string AdName = null;
        private bool isReadyInterTime = false;
        private Action rewardDoneCallBack = null;
        private Action rewardFailedCallBack = null;
        private WaitForSeconds delayRewardTime = new WaitForSeconds(0.1f);
        private WaitLogEvent interLogEvent = new WaitLogEvent(RequestType.Inter);
        private WaitLogEvent rewardLogEvent = new WaitLogEvent(RequestType.Reward);
        private List<int> adCountList = new List<int>() { 1, 5, 10, 15, 20 };

        private string REWARD_AD_COUNT = "PLAYER_AD_COUNT";
        private int m_rewardAdCount;
        public int RewardAdCount {
            get {
                return m_rewardAdCount;
            }
            set {
                m_rewardAdCount = value;
                LogAdCount("Reward", value);
                PlayerPrefs.SetInt(REWARD_AD_COUNT, value);
            }
        }

        private string INTERSTITIAL_AD_COUNT = "PLAYER_INTERSTITIAL_AD_COUNT";
        private int m_intertitialAdCount;
        public int InterstitialAdCount {
            get {
                return m_intertitialAdCount;
            }
            set {
                m_intertitialAdCount = value;
                LogAdCount("Interstitial", value);
                PlayerPrefs.SetInt(INTERSTITIAL_AD_COUNT, value);
            }
        }

        private const string AD_IS_FIRST_OPEN = "AD_IS_FIRST_OPEN";
        private bool m_isFirstOpen;
        public bool IsFirstOpen {
            get => m_isFirstOpen;
            private set {
                m_isFirstOpen = value;
                PlayerPrefs.SetInt(AD_IS_FIRST_OPEN, value ? 1 : -1);
            }
        }

        /// <summary>
        /// 移除插屏
        /// </summary>
        private const string REMOVE_AD_KEY = "REMOVE_NO_KEY";
        private bool m_isRemoveAD;
        public bool IsRemoveAD {
            get => m_isRemoveAD;
            private set {
                m_isRemoveAD = value;
                PlayerPrefs.SetInt(REMOVE_AD_KEY, value ? 1 : -1);
            }
        }

        public bool IsPlayingAD { get; private set; } = false;
        private bool isOpen = false;
        private float interIntervalTime;
        private float cutdownOpenTime;

        public void Init() {
            DontDestroyOnLoad(this);
            m_rewardAdCount = PlayerPrefs.GetInt(REWARD_AD_COUNT);
            m_intertitialAdCount = PlayerPrefs.GetInt(INTERSTITIAL_AD_COUNT);
            m_isRemoveAD = PlayerPrefs.GetInt(REMOVE_AD_KEY, -1) == 1;
            IsFirstOpen = PlayerPrefs.GetInt(AD_IS_FIRST_OPEN, 1) == 1;
            if (SDKBundle.IsEnableOpenIntervalTime()) {
                interIntervalTime = IsFirstOpen ? SDKBundle.GetFirstOpenInterIntervalTime() : SDKBundle.GetOpenInterIntervalTime();
                cutdownOpenTime = interIntervalTime;
                IsFirstOpen = false;
                PlayerPrefs.Save();
            }
            else {
                interIntervalTime = SDKBundle.GetInterIntervalTime();
            }
            curInterTime = interIntervalTime;
            //注册需要的事件
            AdsHandler.Instance.OnInterCloseEvent += OnInterClose;
            AdsHandler.Instance.OnRVCloseEvent += OnRVClose;
            AdsHandler.Instance.OnRVRewardUserEvent += OnRVRewardUser;
            AdsHandler.Instance.OnRVFailedToShowEvent += OnRVFailedToShow;
            AdsHandler.Instance.Init();
        }

        /// <summary>
        /// 插屏计时
        /// </summary>
        private void Update() {
            if (!AdsHandler.Instance.IsInitSuccess)
                return;
            interLogEvent.Update();
            rewardLogEvent.Update();
            if (IsRemoveAD || isReadyInterTime) {
                return;
            }
            if (cutdownOpenTime > 0) {
                cutdownOpenTime -= Time.deltaTime;
                if (cutdownOpenTime <= 0) {
                    cutdownOpenTime = 0;
                    interIntervalTime = SDKBundle.GetInterIntervalTime();
                }
                else
                    return;
            }
            curInterTime += Time.deltaTime;
            if (curInterTime >= interIntervalTime) {
                curInterTime = 0;
                isReadyInterTime = true;
            }
        }

        /// <summary>
        /// 内购移除插屏
        /// </summary>
        [Obsolete("兼容旧版本,现在去广告应在外部脚本中定义")]
        public void RemoveAds() {
            IsRemoveAD = true;
            Debug.Log("【Remove Inter AD Success!");
        }

        /// <summary>
        /// 重置插屏广告计时
        /// </summary>
        private void ResetInterTime() {
            curInterTime = 0;
            isReadyInterTime = false;
        }

        /// <summary>
        /// 广告次数事件
        /// </summary>
        private void LogAdCount(string name, int count) {
            if (adCountList.Contains(count)) {
                string key = $"ad_{name}_Count_{count}";
                //SDKBundle.TrackFaceBookCustomEvent(key);
                SDKBundle.TrackFirebaseCustomEvent(key);
                SDKBundle.TrackSingularCustomEvent(key);
            }
        }

        #region 插屏
        /// <summary>
        /// 判断插屏是否加载成功
        /// </summary>
        /// <returns>返回加载成功判断</returns>
        public bool IsInterstitialADReady() {
            return AdsHandler.Instance.IsInterstitialADReady();
        }

        /// <summary>
        /// 判断插屏是否能展示
        /// </summary>
        public bool IsInterstitialCanShow() {
            return cutdownOpenTime <= 0 && !IsRemoveAD && isReadyInterTime && AdsHandler.Instance.IsInterstitialADReady();
        }

        /// <summary>
        /// 播放插屏广告
        /// </summary>
        public void ShowInterstitialAD() {
#if UNITY_EDITOR
            if (!SDKBundle.IsShowVideo()) {
                return;
            }
#endif
            if (cutdownOpenTime > 0) {
                Debug.Log($"【Skip Inter! CutDown Open Time");
                return;
            }
            if (IsRemoveAD || !isReadyInterTime) {
                Debug.Log($"【Skip Inter! IsRemoveAD_{IsRemoveAD}:InterTime_{isReadyInterTime}");
                return;
            }
            if (IsInterstitialADReady()) {
                AdsHandler.Instance.ShowInterstitialAD();
                InterstitialAdCount++;
                ResetInterTime();
                IsPlayingAD = true;
            }
            else {
                if (interLogEvent.IsReadyLogEvent()) {
                    interLogEvent.AddDelayTime();
                    SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, "ad_Total_Interstitial_Not_Load");
                }
            }
        }

        /// <summary>
        /// 广告关闭回调
        /// </summary>
        private void OnInterClose() {
            IsPlayingAD = false;
            ResetInterTime();
        }
        #endregion

        #region 激励
        /// <summary>
        /// 判断激励视频是否加载成功
        /// </summary>
        /// <returns>返回加载成功判断</returns>
        public bool IsRewardADReady() {
            if (IsRemoveAD) {
                return true;
            }
            return AdsHandler.Instance.IsRewardADReady();
        }

        /// <summary>
        /// 展示激励视频是否加载成功
        /// </summary>
        /// <param name="adName">广告事件类型</param>
        /// <param name="doneCallBack">视频播放完成回调</param>
        /// <param name="failedCallBack">视频播放失败完成回调</param>
        public void ShowRewardAD(string _adName, Action doneCallBack, Action failedCallBack = null) {
#if UNITY_EDITOR
            if (!SDKBundle.IsShowVideo()) {
                doneCallBack?.Invoke();
                return;
            }
#endif
            if (rewardLogEvent.IsReadyLogEvent()) {
                SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_{_adName}_Reward_BtnClick");
            }
            if (!IsRewardADReady()) {
                if (rewardLogEvent.IsReadyLogEvent()) {
                    rewardLogEvent.AddDelayTime();
                    SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, "ad_Total_Reward_Not_Load");
                    SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_{_adName}_Reward_Not_Load");
                }
                return;
            }
            AdName = _adName;
            rewardDoneCallBack = doneCallBack;
            rewardFailedCallBack = failedCallBack;
            SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_{AdName}_Reward_Showed");
            SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_aa_Reward_Showed:ad_{AdName}_Reward_Showed");
            AdsHandler.Instance.ShowRewardAD();
            IsPlayingAD = true;
        }

        /// <summary>
        /// 播放完成
        /// </summary>
        private void OnRVRewardUser() {
            RewardAdCount++;
            SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_{AdName}_Reward_Done");
            AdName = null;
            OnRewardDoneCallBack();
        }

        /// <summary>
        /// 奖励回调
        /// </summary>
        private void OnRewardDoneCallBack() {
            StartCoroutine(CoDeleyRewardDone());
        }

        /// <summary>
        /// 延迟奖励等待主线程执行
        /// </summary>
        IEnumerator CoDeleyRewardDone() {
            yield return delayRewardTime;
            rewardDoneCallBack?.Invoke();
            rewardDoneCallBack = null;
            ResetInterTime();
        }


        /// <summary>
        /// 奖励失败回调
        /// </summary>
        private void OnRVFailedToShow() {
            SDKBundle.TrackCustomEvent(AdsHandler.AD_TOTAL_EVENT, $"ad_{AdName}_Reward_FailedShow");
            rewardFailedCallBack?.Invoke();
            rewardFailedCallBack = null;
        }


        private void OnRVClose() {
            IsPlayingAD = false;
        }

        #endregion

        #region 横幅

        public bool IsBannerADReady() {
            return AdsHandler.Instance.IsBannerLoad;
        }

        /// <summary>
        /// 展示横幅广告
        /// </summary>
        public void ShowBannerAD() {
            AdsHandler.Instance.ShowBanner();
        }

        /// <summary>
        /// 隐藏横幅广告
        /// </summary>
        public void HideBannerAD() {
            AdsHandler.Instance.HideBanner();
        }

        /// <summary>
        /// 彻底销毁横幅广告
        /// </summary>
        public void DestoryannerAD() {
            AdsHandler.Instance.DestroyBanner();
        }

        /// <summary>
        /// 获取横幅广告的高度
        /// </summary>
        public float GetBannerHeigh() {
            return AdsHandler.Instance.GetBannerHeigh();
        }
        #endregion
    }

    public class WaitLogEvent {

        private float waitTime;

        private readonly RequestType m_requestType;
        public RequestType CurType {
            get {
                return m_requestType;
            }
        }

        private const float DELAY_TIME = 5f;

        public WaitLogEvent(RequestType _requestType) {
            m_requestType = _requestType;
            RemoveTime();
        }

        public void Update() {
            if (waitTime > 0) {
                waitTime -= Time.deltaTime;
            }
        }

        public void AddDelayTime() {
            waitTime += DELAY_TIME;
        }

        public void RemoveTime() {
            waitTime = 0;
        }

        public bool IsReadyLogEvent() {
            return waitTime <= 0;
        }
    }
}